namespace ShellNavigator.Client.Core
{
  #region

  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Linq;
  using System.Text;
  using System.Windows;
  using System.Xml;
  using System.Xml.Linq;

  #endregion

  /// <summary>
  ///     The shell executor.
  /// </summary>
  public static class ShellExecutor
  {
    #region Constants and Fields

    private static string lastSolutionName = string.Empty;

    #endregion

    #region Public Methods

    public static void CopyAssemblyName(IEnumerable<string> projectNames)
    {
      var builder = new StringBuilder();
      foreach (var projectName in projectNames)
      {
        builder.AppendLine(GetAssemblyInfo(projectName));
      }

      Clipboard.SetText(builder.ToString());
    }

    public static void CopyAssemblyName(string projectName)
    {
      Clipboard.SetText(GetAssemblyInfo(projectName));
    }

    public static void CopyToClipboard(string fileName)
    {
      Clipboard.SetText(fileName);
    }

    public static void CopyToClipboard(IEnumerable<string> fileNames)
    {
      var builder = new StringBuilder();
      foreach (var fileName in fileNames)
      {
        builder.AppendLine(fileName);
      }

      Clipboard.SetText(builder.ToString());
    }

    public static void OpenShell(string fileName)
    {
      Process.Start(fileName);
    }

    public static void OpenStudio(string solutionName, IEnumerable<string> fileNames)
    {
      if (lastSolutionName == solutionName)
      {
        Process.Start(GetDevEnvPath(), string.Format("/edit {0}", fileNames.Aggregate((acc, f) => acc + " " + f)));
      }
      else
      {
        Process.Start(GetDevEnvPath(), string.Format("{0} {1}", solutionName, fileNames.Aggregate((acc, f) => acc + " " + f)));
        lastSolutionName = solutionName;
      }
    }

    public static void OpenStudio(string solutionName)
    {
      Process.Start(GetDevEnvPath(), solutionName);
    }

    public static void OpenStudio(string solutionName, string fileName)
    {
      if (lastSolutionName == solutionName)
      {
        Process.Start(GetDevEnvPath(), string.Format("/edit {0}", fileName));
      }
      else
      {
        Process.Start(GetDevEnvPath(), string.Format("{0} {1}", solutionName, fileName));
        lastSolutionName = solutionName;
      }
    }

    #endregion

    #region Methods

    /// <summary>
    ///     The copy assembly info.
    /// </summary>
    /// <param name = "fileName">
    ///     The file name.
    /// </param>
    private static string GetAssemblyInfo(string fileName)
    {
      XDocument projectFile;

      try
      {
        projectFile = XDocument.Load(fileName);
      }
      catch (XmlException)
      {
        MessageBox.Show("Invalid project file or solution file selected as target.", "Error reading XML");
        return string.Empty;
      }

      var names = from item in projectFile.Descendants() where item.Name.LocalName == "AssemblyName" select item.Value;

      var name = names.First();

      var types = from item in projectFile.Descendants() where item.Name.LocalName == "OutputType" select item.Value;

      var type = types.First();

      string ext;

      switch (type)
      {
        case "Library":
          ext = ".dll";
          break;
        default:
          ext = ".exe";
          break;
      }

      return name + ext;
    }

    private static string GetDevEnvPath()
    {
      return "devenv";
    }

    #endregion
  }
}